from minio import Minio
from datetime import timedelta
import io
from backend.config.config import settings


class MinioClient:
    def __init__(self):
        # 移除可能的http://或https://前缀
        endpoint = settings.MINIO_ENDPOINT
        if endpoint.startswith("http://"):
            endpoint = endpoint[7:]
        elif endpoint.startswith("https://"):
            endpoint = endpoint[8:]
        
        # 移除末尾的斜杠
        endpoint = endpoint.rstrip('/')
        
        self.client = Minio(
            endpoint=endpoint,
            access_key=settings.MINIO_ACCESS_KEY,
            secret_key=settings.MINIO_SECRET_KEY,
            secure=settings.MINIO_SECURE,
        )
        self.bucket_name = settings.MINIO_BUCKET_NAME

        # 确保 bucket 存在
        if not self.client.bucket_exists(self.bucket_name):
            self.client.make_bucket(self.bucket_name)

    # ========== 内部工具 ==========
    def _make_key(self, path: str, filename: str) -> str:
        """组合路径和文件名，保证格式正确"""
        return f"{path.strip('/')}/{filename}".lstrip("/")

    # ========== 上传 ==========
    def upload_file(self, path: str, filename: str, file_path: str, content_type: str = "application/octet-stream"):
        key = self._make_key(path, filename)
        self.client.fput_object(
            self.bucket_name, key, file_path, content_type=content_type
        )
        return f"{self.bucket_name}/{key}"

    def upload_bytes(self, path: str, filename: str, data: bytes, content_type: str = "application/octet-stream"):
        key = self._make_key(path, filename)
        self.client.put_object(
            self.bucket_name,
            key,
            io.BytesIO(data),
            length=len(data),
            content_type=content_type,
        )
        return f"{self.bucket_name}/{key}"

    # ========== 下载 ==========
    def download_bytes(self, path: str, filename: str) -> bytes:
        key = self._make_key(path, filename)
        response = self.client.get_object(self.bucket_name, key)
        data = response.read()
        response.close()
        response.release_conn()
        return data

    # ========== URL ==========
    def get_presigned_url(self, path: str, filename: str, expires: int = 3600) -> str:
        key = self._make_key(path, filename)
        return self.client.presigned_get_object(
            self.bucket_name,
            key,
            expires=timedelta(seconds=expires)
        )

    # ========== 删除 ==========
    def remove_file(self, path: str, filename: str):
        key = self._make_key(path, filename)
        self.client.remove_object(self.bucket_name, key)

    # ========== 列目录 ==========
    def list_folder(self, path: str):
        """只列出当前目录，不递归"""
        prefix = path.strip("/") + "/"
        objects = self.client.list_objects(self.bucket_name, prefix=prefix, recursive=False)
        return [obj.object_name for obj in objects]

    def list_recursive(self, path: str):
        """递归列出所有子目录文件"""
        prefix = path.strip("/") + "/"
        objects = self.client.list_objects(self.bucket_name, prefix=prefix, recursive=True)
        return [obj.object_name for obj in objects]


# FastAPI 依赖注入方法
def get_minio_client() -> MinioClient:
    return MinioClient()